//
//  DCFlowControl.cpp
//  DCA
//
//  Created by James Critchley on 8/15/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "DCFlowControl.h"


DCFlowControl::DCFlowControl(){
    computation = 0;
}

DCFlowControl::~DCFlowControl(){
}

DCBinarySequentialFlow::DCBinarySequentialFlow(){
    child1 = child2 = 0;
    parent_sync = &null_sync;
}

DCBinarySequentialFlow::~DCBinarySequentialFlow()
{    
}

void DCBinarySequentialFlow::assembly_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();

    child1->assembly_traversal();
    child2->assembly_traversal();
    computation->assemble();
    
    // signal we are done
    parent_sync->SignalParent();
}

void DCBinarySequentialFlow::solve_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();

    computation->solve();        
    child1->solve_traversal();
    child2->solve_traversal();
    
    // signal we are done
    parent_sync->SignalParent();
}


DCFlowTerminator::DCFlowTerminator()
{
    parent_sync = &null_sync;
}

DCFlowTerminator::~DCFlowTerminator()
{
}

void DCFlowTerminator::assembly_traversal()
{    
    // wait for parent
    parent_sync->WaitForParent();

    computation->assemble();
    
    // signal we are done
    parent_sync->SignalParent();
}

void DCFlowTerminator::kinAssembly_traversal()
{    
    // wait for parent
    parent_sync->WaitForParent();

    // Form EOM
    computation->kinAssembly();
    
    // signal we are done
    parent_sync->SignalParent();
}

void DCFlowTerminator::null_traversal()
{    
        // wait for parent
        parent_sync->WaitForParent();

        // NULL
        computation->comp_null();
        
        // signal we are done
        parent_sync->SignalParent();
}

void DCFlowTerminator::kinSolve_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();

    computation->kinSolve();

    // signal we are done
    parent_sync->SignalParent();
}

void DCFlowTerminator::solve_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();

    computation->solve();

    // signal we are done
    parent_sync->SignalParent();
}


DCBinaryParallelFlow::DCBinaryParallelFlow()
{
    child1 = child2 = 0;
    parent_sync = child_sync = &null_sync;
}

void DCBinaryParallelFlow::null_traversal(){
    // wait for parent
    parent_sync->WaitForParent();
    
    // signal the child2 thread to begin processing
    child_sync->SignalChild();
    
    // process child1 on this thread
    child1->null_traversal();
    //child2->assembly_traversal();

    // wait for child to complete
    child_sync->WaitForChild();    
    
    // signal parent that we are done
    parent_sync->SignalParent();
}

DCBinaryParallelFlow::~DCBinaryParallelFlow()
{    
}

void DCBinaryParallelFlow::assembly_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();
    
    // signal the child2 thread to begin processing
    child_sync->SignalChild();
    
    // process child1 on this thread
    child1->assembly_traversal();
    //child2->assembly_traversal();

    // wait for child to complete
    child_sync->WaitForChild();

    // process the local assembly operation
    computation->assemble();
    
    // signal parent that we are done
    parent_sync->SignalParent();
}

void DCBinaryParallelFlow::kinAssembly_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();
    
    // signal the child2 thread to begin processing
    child_sync->SignalChild();
    
    // process child1 on this thread
    child1->kinAssembly_traversal();
    //child2->assembly_traversal();

    // wait for child to complete
    child_sync->WaitForChild();    
    
    // signal parent that we are done
    parent_sync->SignalParent();
}

void DCBinaryParallelFlow::solve_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();

    // process the local solve routine
    computation->solve();
    
    //signal the child2 thread to begin processing
    child_sync->SignalChild();
        
    // process child1 on this thread
    child1->solve_traversal();
    //child2->solve_traversal();

    // wait for child to complete
    child_sync->WaitForChild();
    
    // signal parent that we are done
    parent_sync->SignalParent();
}

void DCBinaryParallelFlow::kinSolve_traversal()
{
    // wait for parent
    parent_sync->WaitForParent();    
    
    computation->kinSolve();
    
    //signal the child2 thread to begin processing
    child_sync->SignalChild();
        
    // process child1 on this thread
    child1->kinSolve_traversal();
    //child2->solve_traversal();

    // wait for child to complete
    child_sync->WaitForChild();
    
    // signal parent that we are done
    parent_sync->SignalParent();
}



